﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Security.Permissions;

using Model.Crafters;
using Model.Raw_Materials;

namespace Model.Items.Weapons.Parts
{
    [Serializable]
    public abstract class MetalPart : Item
    {
        //variables configureable by the builder
        protected int _BarsConsumed; //bars consumed in the process of crafting the item

        protected Metal _Metal;        
        protected Ornament _Ornament;
        protected Skill _Craftmanship;
        protected Skill _Flair;

        public const int Quantity = 1;

        public MetalPart() { } //empty ctor for serialization

        protected MetalPart(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
                throw new System.ArgumentNullException("info");
            CraftingMetal = info.GetValue("CraftingMetal", typeof(Metal)) as Metal;
            BarsConsumed = (int)info.GetValue("BarsConsumed", typeof(int));
            CraftingOrnament = info.GetValue("CraftingOrnament", typeof(Ornament)) as Ornament;
            Craftmanship = info.GetValue("Craftmanship", typeof(Skill)) as Skill;
            Flair = info.GetValue("Flair", typeof(Skill)) as Skill;
        }

        public MetalPart(Crafter crafter, Metal metal, Ornament ornament)
        {
            this.crafter = crafter;
            CraftingMetal = metal;
            CraftingOrnament = ornament;

            Craftmanship = crafter.Skills.Find(delegate(Skill skill) { return skill.SkillType == Skill.SkillTypes.Craftmanship; });
            Flair = crafter.Skills.Find(delegate(Skill skill) { return skill.SkillType == Skill.SkillTypes.Flair; });
            if (Craftmanship == null || Flair == null)
                throw new ArgumentException("Invalid crafter skills supplied for this item " + this);
            //test that there is enough metal to craft the item
            /*if (CraftingMetal.Quantity - BarsConsumed >= 0)
                CraftingMetal.Quantity = CraftingMetal.Quantity - BarsConsumed;
            else
                throw new Exception();//throw some exception*/
        }

        public Metal CraftingMetal
        {
            get { return _Metal; }
            set
            {
                _Metal = value;
                NotifyPropertyChanged("CraftingMetal");
            }
        }

        public override int Quality
        {
            get { return (int)ComputeQuality(CraftingMetal.Quality, Craftmanship.SkillPoints); }
        }

        public override int Aesthetic
        {
            get
            {
                return (int)(ComputeAesthetic(CraftingOrnament.Value, Flair.SkillPoints));
            }
        }

        public int BarsConsumed
        {
            get { return _BarsConsumed; }
            set
            {
                _BarsConsumed = value;
                NotifyPropertyChanged("BarsConsumed");
            }
        }

        public Ornament CraftingOrnament
        {
            get { return _Ornament; }
            set
            {
                _Ornament = value;
                NotifyPropertyChanged("CraftingOrnament");
            }
        }

        public Skill Craftmanship
        {
            get { return _Craftmanship; }
            set
            {
                _Craftmanship = value;
                NotifyPropertyChanged("Craftmanship");
            }
        }

        public Skill Flair
        {
            get { return _Flair; }
            set
            {
                _Flair = value;
                NotifyPropertyChanged("Flair");
            }
        }

        public override string ToString()
        {
            return "Quality: " + Quality + "\nAesthetic: " + Aesthetic;
        }

        [SecurityPermission(SecurityAction.LinkDemand,
        Flags = SecurityPermissionFlag.SerializationFormatter)]
        public override void GetObjectData(
        SerializationInfo info, StreamingContext context)
        {
            if (info == null)
                throw new System.ArgumentNullException("info");
            base.GetObjectData(info, context);
            info.AddValue("CraftingMetal", CraftingMetal);
            info.AddValue("BarsConsumed", BarsConsumed);
            info.AddValue("CraftingOrnament", CraftingOrnament);
            info.AddValue("Craftmanship", Craftmanship);
            info.AddValue("Flair", Flair);
            
        }
    }
}
